﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tasker.Composition;
using Tasker.Infrastructure.Entities;
using Tasker.Infrastructure.Repositories;
using Tasker.Infrastructure.Repositories.Base;
using Tasker.Repositories.Entities;

namespace Tasker.Repositories.Repositories
{
    public class TasksRepositoryEF : ITasksRepository
    {
        private EntitiesContext _context = Resolver.Resolve<EntitiesContext>();
        private IContextManager _manager = Resolver.Resolve<IContextManager>();

        public ITask SelectById(int id)
        {
            return _context.Tasks.SingleOrDefault(user => user.Id == id);
        }

        public ITask SelectByUserTime(int userId, DateTime CreatedDate)
        {
            return _context.Tasks.SingleOrDefault(ts => ts.AuthorId == userId && ts.CreatedDate == CreatedDate);
        }

        public IEnumerable<ITask> SelectByUserIncoming(int userId)
        {
            return _context.Tasks.Include("TaskWorkers")
                .Where(t => t.TaskWorkers
                    .Any(tw => tw.UserId == userId))
                .OrderByDescending(t => t.CreatedDate);
        }

        public IEnumerable<ITask> SelectByUserOutcoming(int userId)
        {
            return _context
                .Tasks
                .Where(t => t.AuthorId == userId)
                .OrderByDescending(t => t.CreatedDate);
        }

        public IEnumerable<ITask> SelectAll()
        {
            return _context.Tasks.OrderByDescending(t => t.CreatedDate).ToList();
        }

        public IEnumerable<ITask> SelectSubTasks(int taskId)
        {
            return _context.Tasks.Where(t => t.ParentId == taskId);
        }

        public void Update(ITask entity)
        {
            Task task = _context.Tasks.SingleOrDefault(tk => tk.Id == entity.Id);
            task.Name = entity.Name;
            task.Description = entity.Description;
            task.CreatedDate = entity.CreatedDate;
            task.StartDate = entity.StartDate;
            task.FinishDate = entity.FinishDate;
            task.AuthorId = entity.AuthorId;
            _manager.Save();   
        }

        public ITask Create()
        {
            return new Task();
        }

        public void Delete(ITask entity)
        {
            IEnumerable<ITask> tasks = _context.Tasks.Where(ts => ts.ParentId == entity.Id);
            foreach (var ts in tasks)
            {
                Delete(ts);
            }
            Task task = _context.Tasks.SingleOrDefault(ts => ts.Id == entity.Id);
            _context.Tasks.DeleteObject(task);   
        }

        public ITask Insert(ITask entity)
        {
            Task ts = entity as Task;
            _context.Tasks.AddObject(ts);
            _manager.Save();
            return ts;
        }
    }
}
